package com.kaili.db.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.kaili.pojo.dto.finance.FinTrans;
import com.kaili.pojo.dto.trans.TransAddBean;
import com.kaili.pojo.dto.trans.TransCheckBean;
import com.kaili.pojo.dto.trans.TransModifyBean;
import com.kaili.client.service.ILoginUserInfoService;
import com.kaili.client.service.IPdaService;
import com.kaili.common.OperationType;
import com.kaili.common.stock.StockPdaInfoBean;
import com.kaili.db.mapper.HsEwbsTransferMapper;
import com.kaili.db.service.*;
import com.kaili.pojo.entity.*;
import com.kaili.pojo.vo.TransCheckVo;
import com.kaili.pojo.vo.TransExportVo;
import com.kaili.pojo.vo.TransSendVo;
import com.kaili.common.exception.BaseExcept;
import com.kaili.except.ResponseStatus;
import com.kaili.utils.DateUtils;
import com.kaili.common.util.SnowflakeIdFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

import static com.kaili.except.ResponseStatus.*;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author cgm
 * @since 2018-05-08
 */
@Service
@Transactional
public class HsEwbsTransferServiceImpl extends ServiceImpl<HsEwbsTransferMapper, HsEwbsTransfer> implements IHsEwbsTransferService {
    @Autowired
    ILoginUserInfoService loginUserInfoService;
    @Autowired
    IPdaService pdaService;
    @Autowired
    IHsOptQueryService queryService;
    @Autowired
    IHsEwbsTransferDetailService transferDetailService;
    @Autowired
    IHsOptEwbService ewbService;
    @Autowired
    IHsEwbsSignDetailService signDetailService;
    @Autowired
    IHsEwbSubStockService stockService;

    @Override
    public List<TransSendVo> getTransferSendList(Map search) {
        return baseMapper.getTransferSendList(search);
    }

    @Override
    public List<TransSendVo> getTransferArriveList(Map search) {
        return baseMapper.getTransferArriveList(search);
    }

    @Override
    public Page<TransSendVo> getTransferSendList(Page<TransSendVo> page, Map search) {
        return page.setRecords(baseMapper.getTransferSendList(page, search));
    }

    @Override
    public Page<TransSendVo> getTransferArriveList(Page page, Map search) {
        return page.setRecords(baseMapper.getTransferArriveList(page, search));
    }

    private int addSend(TransAddBean bean) {
        bean.setCreatedTime(DateUtils.getCurrentDate());
        String optId = String.valueOf(SnowflakeIdFactory.getNextId());
        bean.setOperationId(optId);
        List<HsEwbsTransferDetail> lst = bean.getLst();
        List<HsEwbsTransferDetail> details = new ArrayList<>();
        List<HsOptQuery> queries = new ArrayList<>();
        for (int i = 0; i < lst.size(); i++) {
            HsEwbsTransferDetail detail = lst.get(i);
            detail.setDeviceCode(bean.getDeviceCode());
            detail.setScanSourceId(bean.getScanSourceId());
            detail.setTransferNo(optId);
            detail.setSiteId(bean.getSiteId());
            if (transferDetailService.hasTransed(detail)) {
                throw new BaseExcept(TRANS_ADD_DUPLICATE);
            }
            List<HsEwbSubStock> stockList = stockService.getStockListBySiteId(bean.getSiteId(), detail.getEwbNo(), OperationType.STOCK_ON);
            if (stockList == null || stockList.size() < detail.getPiece()) {
                throw new BaseExcept(TRANS_STOCK_NOT_ENOUGH_ERR);
            }
            details.add(detail);
            StockPdaInfoBean stockPdaInfoBean = new StockPdaInfoBean();
            stockPdaInfoBean.setEwbNo(detail.getEwbNo());
            List<String> subEwbs = new ArrayList<>();
            for (int j = 0; j < stockList.size(); j++) {
                subEwbs.add(stockList.get(j).getSubEwb());
            }
            stockPdaInfoBean.setSubEwbs(subEwbs);
            stockPdaInfoBean.setSiteId(detail.getSiteId());
            if (bean.getTransType() == 0) {
                //发货中转
                stockPdaInfoBean.setNextSiteId(bean.getNextSiteId());
            } else {
                //到货中转
                stockPdaInfoBean.setNextSiteId(0);
            }
            stockPdaInfoBean.setSize(detail.getPiece());
            stockService.transEwbByPda(stockPdaInfoBean);
            HsOptQuery query = new HsOptQuery();
            query.setEwbNo(detail.getEwbNo());
            query.setStep(OperationType.TRANS);
            query.setOperationTime(DateUtils.getCurrentDate());
            query.setOperationId(optId);
            query.setOperationSiteId(bean.getSiteId());
            query.setOperator(bean.getCreatedBy());
            queries.add(query);
        }
        queryService.insertBatch(queries);
        baseMapper.insert(bean);
        transferDetailService.insertBatch(details);
        /*-----------调用财务存储过程--------------*/
        toFinTrancInfo(bean, "1", bean.getCreatedBy(), bean.getCreatedTime());
        return 0;
    }

    /**
     * 封装调用财务存储过程包
     *
     * @param bean
     * @param type
     * @return
     */
    void toFinTrancInfo(TransAddBean bean, String type, int optId, Date optTime) {
        FinTrans transAdd = new FinTrans();
        transAdd.setOperation_id(bean.getOperationId());
        transAdd.setCreated_by(optId);
        transAdd.setCreated_time(DateUtils.dateToStrLong(optTime));
        transAdd.setCarry_charge(bean.getCarryCharge().doubleValue());
        transAdd.setNext_site_id(bean.getNextSiteId());
        transAdd.setRemark(bean.getRemark());
        transAdd.setSite_id(bean.getSiteId());
        transAdd.setTransfer_charge(bean.getTransferCharge().doubleValue());
        transAdd.setEwb_no("");
        transAdd.setOperate_type(type);
        List<FinTrans> details = new ArrayList<>();
        details.add(transAdd);
        Map info = new HashMap();
        info.put("info", JSON.toJSONString(details));
        stockService.pFinEwbsTransferInput(info);
    }

    @Override
    public int addTransSend(TransAddBean bean) {
        bean.setDeviceCode("BS");
        bean.setScanSourceId(0);
        bean.setCreatedBy(loginUserInfoService.getLoginUserId());
        //bean.setSiteId(loginUserInfoService.getLoginSiteId());
        return addSend(bean);
    }

    @Override
    public int modifyTrans(TransModifyBean bean) {
        Map search = new HashMap();
        search.put("transfer_no", bean.getOperationId());
        search.put("rd_status", 1);
        List<HsEwbsTransferDetail> details = transferDetailService.selectByMap(search);
        List<HsEwbsTransferDetail> updates = new ArrayList<>();
        List<HsEwbsTransferDetail> orgs = new ArrayList<>();
        List<HsEwbsTransferDetail> deletes = new ArrayList<>();
        // 获取新增及原始数据
        for (int j = 0; j < bean.getLst().size(); j++) {
            HsEwbsTransferDetail n = bean.getLst().get(j);
            HsEwbsTransferDetail org = null;
            boolean has = false;
            for (int i = 0; i < details.size(); i++) {
                org = details.get(i);
                if (n.getEwbNo().equals(org.getEwbNo())) {
                    has = true;
                    break;
                }
            }
            if (!has) {
                insertTransDetaisl(bean.getOperationId(), bean.getOperatorId(), n);
                //updates.add(n);
            } else {
                orgs.add(n);
            }
        }
        // 获取删除数据
        for (int i = 0; i < orgs.size(); i++) {
            HsEwbsTransferDetail n = orgs.get(i);
            HsEwbsTransferDetail org = null;
            boolean has = false;
            for (int j = 0; j < details.size(); j++) {
                org = deletes.get(j);
                if (org.getEwbNo().equals(n.getEwbNo())) {
                    has = true;
                    break;
                }
            }
            if (!has) {
                deleteTransDetaisl(bean.getOperationId(), bean.getOperatorId(), n);
                //dele+++--tes.add(n);
            }
        }
        return modifyTransInfo(bean);
    }

    private int modifyTransInfo(TransModifyBean bean) {
        bean.setModifiedTime(DateUtils.getCurrentDate());
        bean.setModifiedBy(bean.getOperatorId());

        /*-----------调用财务存储过程--------------*/
        toFinTrancInfo(bean, "2", bean.getModifiedBy(), bean.getModifiedTime());
        return baseMapper.updateById(bean);
    }

    private int insertTransDetaisl(String id, Integer operatorId, HsEwbsTransferDetail detail) {
        detail.setTransferNo(id);
        /****-----------调整库开始-------------------****/
        List<HsEwbSubStock> stockList = stockService.getStockListBySiteId(detail.getSiteId(), detail.getEwbNo(), OperationType.STOCK_ON);
        if (stockList == null || stockList.size() < detail.getPiece()) {
            throw new BaseExcept(TRANS_STOCK_NOT_ENOUGH_ERR);
        }
        StockPdaInfoBean stockPdaInfoBean = new StockPdaInfoBean();
        stockPdaInfoBean.setEwbNo(detail.getEwbNo());
        List<String> subEwbs = new ArrayList<>();
        for (int j = 0; j < stockList.size(); j++) {
            subEwbs.add(stockList.get(j).getSubEwb());
        }
        stockPdaInfoBean.setSubEwbs(subEwbs);
        stockPdaInfoBean.setSiteId(detail.getSiteId());
        stockPdaInfoBean.setNextSiteId(0);
        stockService.transEwbByPda(stockPdaInfoBean);
        /****-----------调整库结束-------------------****/
        /****-----------插入跟踪记录开始-------------------****/
        HsOptQuery query = new HsOptQuery();
        query.setEwbNo(detail.getEwbNo());
        query.setStep(OperationType.TRANS);
        query.setOperationTime(DateUtils.getCurrentDate());
        query.setOperationId(id);
        query.setOperationSiteId(detail.getSiteId());
        query.setOperator(operatorId);
        queryService.insert(query);
        transferDetailService.insert(detail);
        return 0;
    }

    private int transStockRollBack(HsEwbsTransferDetail detail) {
        /**------------------库存回退开始-----------------------**/
        Map updateInfo = new HashMap();
        updateInfo.put("siteId", detail.getSiteId());
        updateInfo.put("ewbNo", detail.getEwbNo());
        updateInfo.put("status", OperationType.STOCK_ON);
        List<HsEwbSubStock> stocks = stockService.getStockListBySiteId(detail.getSiteId(), detail.getEwbNo(), OperationType.STOCK_TRANS);
        if (stocks.size() < detail.getPiece()) {
            throw new BaseExcept(NOT_ENOUGH_STOCK);
        }
        List<HsEwbSubStock> subs = null;
        if (stocks.size() == detail.getPiece()) {
            subs = stocks;
        } else {
            subs = new ArrayList<>();
            for (int i = 0; i < detail.getPiece(); i++) {
                subs.add(stocks.get(i));
            }
        }
        updateInfo.put("subs", subs);
        stockService.updateBatch(updateInfo);
        /**------------------库存回退结束-----------------------**/
        return 0;
    }

    private int deleteTransDetaisl(String id, Integer operatorId, HsEwbsTransferDetail detail) {
        transStockRollBack(detail);
        queryService.deleteQueryInfo(detail.getEwbNo(), id);
        Wrapper<HsEwbsTransferDetail> wrapper = new EntityWrapper<>();
        wrapper.where("transfer_no={0} and ewb_no={1}", id, detail.getEwbNo());
        transferDetailService.delete(wrapper);
        return 0;
    }

    @Override
    public int deleteTrans(String id) {
        HsEwbsTransfer hsEwbsTransfer = new HsEwbsTransfer();
        hsEwbsTransfer.setOperationId(id);
        hsEwbsTransfer.setRdStatus(0);
        HsEwbsTransferDetail hsEwbsTransferDetail = new HsEwbsTransferDetail();
        hsEwbsTransferDetail.setRdStatus(0);
        Wrapper<HsEwbsTransferDetail> wrapper = new EntityWrapper<>();
        wrapper.where("transfer_no={0}", id);
        List<HsEwbsTransferDetail> list = transferDetailService.selectList(wrapper);
        for (int i = 0; i < list.size(); i++) {
            transStockRollBack(list.get(i));
            queryService.deleteQueryInfo(list.get(i).getEwbNo(), id);
        }
        //hsEwbsTransferDetail.setTransferNo(id);
        transferDetailService.update(hsEwbsTransferDetail, wrapper);
        FinTrans finTrans = new FinTrans();
        finTrans.setOperate_type("3");
        finTrans.setOperation_id(id);
        finTrans.setCreated_time(DateUtils.getStringDate());
        finTrans.setSite_id(loginUserInfoService.getLoginSiteId());
        finTrans.setCreated_by(loginUserInfoService.getLoginUserId());
        List<FinTrans> details = new ArrayList<>();
        details.add(finTrans);
        Map info = new HashMap();
        info.put("info", JSON.toJSONString(details));
        stockService.pFinEwbsTransferInput(info);
        return baseMapper.updateById(hsEwbsTransfer);
    }

    @Override
    public int addTransArrive(TransAddBean bean) {
        return addTransSend(bean);
    }

    @Override
    public int addTransSendPda(TransAddBean bean) {
        bean.setScanSourceId(pdaService.getSouceIdByCode(bean.getDeviceCode()));
        return addSend(bean);
    }

    @Override
    public int addTransArrivePda(TransAddBean bean) {
        bean.setScanSourceId(pdaService.getSouceIdByCode(bean.getDeviceCode()));
        return addSend(bean);
    }

    @Override
    public List<TransExportVo> getTransList(Map search) {
        search.put("rdStatus", 1);
        return baseMapper.getTransList(search);
    }

    @Override
    public Page<TransExportVo> getTransList(Page<TransExportVo> page, Map search) {
        search.put("rdStatus", 1);
        return page.setRecords(baseMapper.getTransList(page, search));
    }

    @Override
    public List<TransSendVo> getTransDetail(Map search) {
        search.put("rdStatus", 1);
        return baseMapper.getTransDetail(search);
    }

    @Override
    public Page<TransCheckVo> getTransCheckList(Page<TransCheckVo> page, Map search) {
        search.put("rdStatus", 1);
        return page.setRecords(baseMapper.getTransCheck(page, search));
    }

    @Override
    public List<TransCheckVo> getTransCheckList(Map search) {
        search.put("rdStatus", 1);
        return baseMapper.getTransCheck(search);
    }

    /**
     * 中转到货处理,添加签收记录
     *
     * @param bean
     * @return
     */
    @Override
    public int doConfirmCheck(List<TransCheckBean> bean) {
        List<HsOptQuery> queries = new ArrayList<>();
        Map<String, Object> map = new HashMap();
        List<HsEwbsSignDetail> signDetailList = new ArrayList<>();
        for (int i = 0; i < bean.size(); i++) {
            TransCheckBean checkBean = bean.get(i);
            HsEwbsTransferDetail detail = new HsEwbsTransferDetail();
            detail.setEwbNo(checkBean.getEwbs());
            detail.setCheckTime(checkBean.getOptTime());
            detail.setCheckBy(checkBean.getOperatorId());
            detail.setSiteId(checkBean.getSiteId());
            Wrapper<HsEwbsTransferDetail> wrapper = new EntityWrapper<>();
            wrapper.where("ewb_no={0} and rd_status={1}", checkBean.getEwbs(), 1).and("site_id={0}", checkBean.getSiteId()).isNotNull("check_by");
            HsEwbsTransferDetail obj = (HsEwbsTransferDetail) transferDetailService.selectObj(wrapper);
            if (obj != null && obj.getCheckBy() != null) {
                throw new BaseExcept(ResponseStatus.TRANS_CHECK_DUPLICATE);
            }
            map.put("checkTime", checkBean.getOptTime());
            map.put("checkBy", checkBean.getOperatorId());
            map.put("deviceCode", checkBean.getPdaCode());
            map.put("siteId", checkBean.getSiteId());
            map.put("ewbNo", checkBean.getEwbs());
            transferDetailService.updateTrans(map);
            HsOptQuery query = new HsOptQuery();
            query.setEwbNo(detail.getEwbNo());
            query.setStep(OperationType.SIGNING);
            query.setOperationTime(DateUtils.getCurrentDate());
            query.setOperationId(checkBean.getOptId());
            query.setOperationSiteId(checkBean.getSiteId());
            query.setOperator(checkBean.getOperatorId());
            queries.add(query);
            ewbService.doSignByEwb(checkBean.getEwbs());
            HsEwbsSignDetail ewbsSignDetail = new HsEwbsSignDetail();
            ewbsSignDetail.setSignNo(checkBean.getOptId());
            if (checkBean.getPdaCode().toUpperCase().equals("BS")) {
                ewbsSignDetail.setScanSourceId(0);
                ewbsSignDetail.setDeviceCode("");
            } else {
                ewbsSignDetail.setScanSourceId(pdaService.getSouceIdByCode(checkBean.getPdaCode()));
                ewbsSignDetail.setDeviceCode(checkBean.getPdaCode());
            }
            ewbsSignDetail.setCreatedTime(DateUtils.getCurrentDate());
            ewbsSignDetail.setScanTime(checkBean.getOptTime());
            ewbsSignDetail.setScanBy(checkBean.getOperatorId());
            ewbsSignDetail.setSiteId(checkBean.getSiteId());
            signDetailList.add(ewbsSignDetail);
        }
        signDetailService.insertBatch(signDetailList);
        queryService.insertBatch(queries);

        return 0;
    }


}
